﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Script.Serialization;
using MyMeta;
using System.IO;
using Liger.Generate;
using Liger.Model;
using Liger.Common;
using Liger.Data;
public static class AjaxDbHelper
{
    public static dbDriver GetDbDriver(string dbType)
    {
        switch(dbType.ToLower())
        {
            case "access":
                return dbDriver.Access;
            default:
                return dbDriver.SQL;
        }
    }

    public static DatabaseType GetDatabaseType(string dbType)
    {
        switch (dbType.ToLower())
        {
            case "access":
                return DatabaseType.MsAccess;
            default:
                return DatabaseType.SqlServer9;
        }
    }

    public static AjaxResult TryConnect(string dbType,string connectionString)
    {
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            if (string.IsNullOrEmpty(connectionString))
                throw new Exception("连接字符串不能为空");
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                return AjaxResult.Success(true);
            }
            return AjaxResult.CreateError("连接失败");
        }
        catch(Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        } 
    }


    public static AjaxResult GetDb(string dbType, string connectionString)
    {
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                return AjaxResult.Success(new
                {
                    name = root.DefaultDatabase.Name,
                    dbType = dbType,
                    connectionString = connectionString
                });
            }
            return AjaxResult.CreateError("链接失败");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }
    public static AjaxResult GetSettings()
    {
        try
        {
            var settings = SettingXMLHelper.GetSettings();
            return AjaxResult.Success(settings);
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

    public static AjaxResult AddDbSetting(string dbType, string connectionString)
    {
        try
        {
            if (SettingXMLHelper.ExistSetting(connectionString))
            {
                throw new Exception("此数据库链接已经存在");
            }
            var root = new MyMeta.dbRoot();
            var driver = GetDbDriver(dbType);
        
            root.Connect(driver, connectionString); 
            if (root.IsConnected)
            {
                var setting = SettingXMLHelper.AddSetting(root.DefaultDatabase.Name, dbType, connectionString);
                return AjaxResult.Success(setting);
            }
            else
            {
                return AjaxResult.CreateError("数据库链接失败");
            }
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }


    public static AjaxResult RemoveDbSetting(string connectionString)
    {
        try
        {
            SettingXMLHelper.RemoveSetting(connectionString);
            return AjaxResult.Success("删除成功");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

    public static AjaxResult GetTables(string dbType, string connectionString, string db)
    {
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var tables = root.DefaultDatabase.Tables;
                var list = new List<TreeTable>();
                foreach (ITable table in tables)
                {
                    list.Add(new TreeTable()
                    {
                        name = table.Name,
                        dbType = dbType,
                        connectionString = connectionString
                    });
                }
                return AjaxResult.Success(list);
            }
            return AjaxResult.CreateError("链接失败");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }


    public static AjaxResult GetTablesDetail(string dbType, string connectionString, string include)
    {
        string[] includes = null;
        if (!string.IsNullOrEmpty(include))
        {
            includes = include.Split(',');
        }
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var tables = root.DefaultDatabase.Tables;
                var views = root.DefaultDatabase.Views;
                var list = new List<object>();
                foreach (ITable t in tables)
                {
                    if (includes != null && !includes.Contains(t.Name))
                        continue;
                    list.Add(new TableBase(t));
                }
                foreach (IView v in views)
                {
                    if (includes != null && !includes.Contains(v.Name))
                        continue;
                    list.Add(new ViewBase(v));
                }
                return AjaxResult.Success(list);
            }
            return AjaxResult.CreateError("链接失败");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

    public static AjaxResult GetViews(string dbType, string connectionString, string db)
    {
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var views = root.DefaultDatabase.Views;
                var list = new List<TreeView>();
                foreach (IView view in views)
                {
                    list.Add(new TreeView()
                    {
                        name = view.Name,
                        dbType = dbType,
                        connectionString = connectionString
                    });
                }
                return AjaxResult.Success(list);
            }
            return AjaxResult.CreateError("链接失败");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

    public static AjaxResult GetColumns(string dbType, string connectionString, string table)
    {
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var tables = root.DefaultDatabase.Tables;
                var list = new List<TreeColumn>();
                foreach (ITable t in tables)
                {
                    if (t.Name == table)
                    {
                        foreach (IColumn column in t.Columns)
                        {
                            list.Add(new TreeColumn()
                            {
                                name = column.Name,
                                isInPrimaryKey = column.IsInPrimaryKey,
                                isInForeignKey = column.IsInForeignKey,
                                dbType = dbType,
                                connectionString = connectionString
                            });
                        }
                        break;
                    }
                }
                return AjaxResult.Success(list);
            }
            return AjaxResult.CreateError("链接失败");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

    public static AjaxResult GetViewColumns(string dbType, string connectionString, string view)
    {
        var root = new MyMeta.dbRoot();
        var driver = GetDbDriver(dbType);
        try
        {
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var views = root.DefaultDatabase.Views;
                var list = new List<TreeColumn>();
                foreach (IView t in views)
                {
                    if (t.Name == view)
                    {
                        foreach (IColumn column in t.Columns)
                        {
                            list.Add(new TreeColumn()
                            {
                                name = column.Name,
                                isInPrimaryKey = column.IsInPrimaryKey,
                                isInForeignKey = column.IsInForeignKey,
                                dbType = dbType,
                                connectionString = connectionString
                            });
                        }
                        break;
                    }
                }
                return AjaxResult.Success(list);
            }
            return AjaxResult.CreateError("链接失败");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

    private static void OutputFile(string filepath, string content)
    {
        var dir = Directory.GetDirectoryRoot(filepath);
        if (!Directory.Exists(dir))
        {
            Directory.CreateDirectory(dir);
        }
        var writer = new StreamWriter(filepath, false, System.Text.Encoding.UTF8);
        writer.Write(content);
        writer.Flush();
        writer.Close(); 
    }

    private static bool ExistMenu(DbContext db,string menuno)
    {
       return db.From<SysMenu>().Where(SysMenu._.MenuNo == menuno).Any();
    }
    private static bool ExistButton(DbContext db, string menuno, string buttonno)
    {
        return db.From<SysButton>().Where(SysButton._.MenuNo == menuno && SysButton._.BtnNo == buttonno).Any();
    }
    private static void InsertMenu(DbContext DB, string url, string MenuNo, string title, string parentMenuNo)
    {
        if (!ExistMenu(DB, parentMenuNo))
        {
            var menu = new SysMenu()
            { 
                MenuNo = parentMenuNo,
                MenuName = parentMenuNo,
                MenuIcon = "../lib/icons/silkicons/folder.png"
            };
            DB.Insert<SysMenu>(menu);
        }

        if (!ExistMenu(DB, MenuNo))
        {
            var menu = new SysMenu()
            {
                MenuUrl = url,
                MenuNo = MenuNo,
                MenuName = title,
                MenuParentNo = parentMenuNo,
                MenuIcon = "../lib/icons/silkicons/application.png"
            };
            DB.Insert<SysMenu>(menu);
        }
        if (ExistMenu(DB, MenuNo))
        {
            try
            {
                DB.BeginTransaction();
                if (!ExistButton(DB, MenuNo, "add"))
                {
                    DB.Insert<SysButton>(new SysButton()
                    {
                        MenuNo = MenuNo,
                        BtnName = "增加",
                        BtnNo = "add",
                        BtnIcon = "lib/icons/silkicons/add.png"
                    });
                } 
                if (!ExistButton(DB, MenuNo, "modify"))
                {
                    DB.Insert<SysButton>(new SysButton()
                    {
                        MenuNo = MenuNo,
                        BtnName = "修改",
                        BtnNo = "modify",
                        BtnIcon = "lib/icons/silkicons/application_edit.png"
                    });
                } if (!ExistButton(DB, MenuNo, "delete"))
                {
                    DB.Insert<SysButton>(new SysButton()
                    {
                        MenuNo = MenuNo,
                        BtnName = "删除",
                        BtnNo = "delete",
                        BtnIcon = "lib/icons/silkicons/delete.png"
                    });
                } if (!ExistButton(DB, MenuNo, "view"))
                {
                    DB.Insert<SysButton>(new SysButton()
                    {
                        MenuNo = MenuNo,
                        BtnName = "查看",
                        BtnNo = "view",
                        BtnIcon = "lib/icons/silkicons/application_view_detail.png"
                    });
                }
                DB.CommitTransaction();
                DB.CloseTransaction();
            }
            catch (Exception err)
            {
                DB.RollbackTransaction();
                DB.CloseTransaction();
            }
        }

    }

    public static AjaxResult InsertSystemDb(string dbType, string connectionString, string parentMenuNo, string include, string dbConnection,string category)
    {
        try
        {
            var context = new DbContext(GetDatabaseType(dbType), dbConnection);

            string[] includes = null;
            if (!string.IsNullOrEmpty(include))
            {
                includes = include.Split(',');
            }
            var root = new MyMeta.dbRoot();
            var driver = GetDbDriver(dbType); 
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var tables = root.DefaultDatabase.Tables;
                var list = new List<PageModel>();
                foreach (ITable t in tables)
                {
                    if (includes != null && !includes.Contains(t.Name))
                        continue;
                    var helper = new NVelocityHelper();
                    var m = new TableBase(t);
                    list.Add(new PageModel()
                    {
                        Name = m.Name,
                        Description = m.Description
                    });
                }

                var views = root.DefaultDatabase.Views;
                foreach (IView v in views)
                {
                    if (includes != null && !includes.Contains(v.Name))
                        continue;
                    var helper = new NVelocityHelper();
                    var m = new ViewBase(v);
                    list.Add(new PageModel()
                    {
                        Name = v.Name,
                        Description = v.Description
                    });
                }

                foreach (var model in list)
                {
                    string url = category + "/" + model.ClassName + ".aspx";
                    InsertMenu(context, url, model.MenuNo, model.Description, parentMenuNo);
                }
            }
                 
            return AjaxResult.Success("成功");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }


    public static AjaxResult GenerateUI(string data, string path, string category)
    {
        try
        {
            path = path + "\\" + category;
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            var list = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<List<PageModel>>(data);


            foreach (var p in list)
            {
                p.Category = category;

                var helper = new NVelocityHelper();
                helper.Add("Model", p); 

                var code1 = helper.Output("list.vtl");
                var code2 = helper.Output("detail.vtl");

                OutputFile(path + "/" + p.ClassName + ".aspx", code1);
                OutputFile(path + "/" + p.ClassName + "Detail.aspx", code2);
            }
            return AjaxResult.Success("生成成功");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }


    public static AjaxResult GenerateEntity(string dbType, string connectionString, string path, string space, string include, bool? copyright)
    { 
        try
        {
            string[] includes = null;
            if (!string.IsNullOrEmpty(include))
            {
                includes = include.Split(',');
            }
            var root = new MyMeta.dbRoot();
            var driver = GetDbDriver(dbType);
            path = path + "\\entity";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var tables = root.DefaultDatabase.Tables; 
                foreach (ITable t in tables)
                {
                    if (includes != null && !includes.Contains(t.Name)) 
                        continue;
                    var helper = new NVelocityHelper();
                    helper.Add("Table", new TableBase(t));
                    helper.Add("Namespace", space);
                    helper.Add("Copyright", copyright != null && copyright.Value ? true : false);
                    var code = helper.Output("entity.vtl");
                    OutputFile(path + "/" + DbTemplateHepler.GetClassName(t.Name) + ".cs", code);
                }

                var views = root.DefaultDatabase.Views;
                foreach (IView v in views)
                {
                    if (includes != null && !includes.Contains(v.Name)) 
                        continue;
                    var helper = new NVelocityHelper();
                    helper.Add("Table", new ViewBase(v));
                    helper.Add("Namespace", space);
                    helper.Add("Copyright", copyright != null && copyright.Value  ? true : false);
                    var currentPath = path;
                    var code = helper.Output("entity.vtl");
                    OutputFile(path + "/" + DbTemplateHepler.GetClassName(v.Name) + ".cs", code);
                } 
            }
            return AjaxResult.Success("生成成功");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }


    public static AjaxResult GenerateServer(string dbType, string connectionString, string path, string space, string include, bool? copyright)
    {
        try
        {
            string[] includes = null;
            if (!string.IsNullOrEmpty(include))
            {
                includes = include.Split(',');
            }
            var root = new MyMeta.dbRoot();
            var driver = GetDbDriver(dbType);
            path = path + "\\server";
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            root.Connect(driver, connectionString);
            if (root.IsConnected)
            {
                var tables = root.DefaultDatabase.Tables;
                foreach (ITable t in tables)
                {
                    if (includes != null && !includes.Contains(t.Name))
                        continue;
                    var helper = new NVelocityHelper();
                    helper.Add("Table", new TableBase(t));
                    helper.Add("Namespace", space);
                    helper.Add("Copyright", copyright != null && copyright.Value ? true : false);
                    var code = helper.Output("server.vtl");
                    OutputFile(path + "/" + "Ajax" + DbTemplateHepler.GetClassName(t.Name) + ".cs", code);
                }

                var views = root.DefaultDatabase.Views;
                foreach (IView v in views)
                {
                    if (includes != null && !includes.Contains(v.Name))
                        continue;
                    var helper = new NVelocityHelper();
                    helper.Add("Table", new ViewBase(v));
                    helper.Add("Namespace", space);
                    helper.Add("Copyright", copyright != null && copyright.Value ? true : false);
                    var currentPath = path;
                    var code = helper.Output("server.vtl");
                    OutputFile(path + "/" + "Ajax" + DbTemplateHepler.GetClassName(v.Name) + ".cs", code);
                }
            }
            return AjaxResult.Success("生成成功");
        }
        catch (Exception err)
        {
            return AjaxResult.CreateError(err.Message);
        }
    }

} 
 